home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-25 | 17.9 KB | 581 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: Frame.cpp
- // Release Version: $ ODF 1 $
- //
- // Author: Laurent Delamare
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "Form.hpp"
-
- #ifndef FRAME_H
- #include "Frame.h"
- #endif
-
- #ifndef DIALOG_H
- #include "Dialog.h"
- #endif
-
- #ifndef PART_H
- #include "Part.h"
- #endif
-
- #ifndef FORMVIEW_H
- #include "FormView.h"
- #endif
-
- #ifndef EDITCMD_H
- #include "EditCmd.h"
- #endif
-
- // ----- Framework Layer -----
-
- #ifndef FWBUTTON_H
- #include "FWButton.h"
- #endif
-
- #ifndef FWTABBER_H
- #include "FWTabber.h"
- #endif
-
- #ifndef FWIDLE_H
- #include "FWIdle.h"
- #endif
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- #ifndef FWSCROLR_H
- #include "FWScrolr.h"
- #endif
-
- #ifndef FWSCLBAR_H
- #include "FWSclBar.h"
- #endif
-
- #ifndef FWGROWBX_H
- #include "FWGrowBx.h"
- #endif
-
- #ifndef FWBUTTON_H
- #include "FWButton.h"
- #endif
-
- #ifndef FWPOPUP_H
- #include "FWPopup.h"
- #endif
-
- #ifndef FWCONTXT_H
- #include "FWContxt.h"
- #endif
-
- #ifndef FWPRHDLR_H
- #include "FWPrHdlr.h"
- #endif
-
- // ----- OS Layer -----
-
- #ifndef FWMENU_H
- #include "FWMenu.h"
- #endif
-
- #ifndef FWEVENT_H
- #include "FWEvent.h"
- #endif
-
- #ifndef FWALERT_H
- #include "FWAlert.h"
- #endif
-
- #ifndef SLMixOS_H
- #include "SLMixOS.h"
- #endif
-
- #ifndef FWCFMRES_H
- #include "FWCFMRes.h"
- #endif
-
- // ----- Graphic Includes -----
-
- #ifndef FWRECT_H
- #include "FWRect.h"
- #endif
-
- #ifndef FWTXTBOX_H
- #include "FWTxtBox.h"
- #endif
-
- #ifndef FWRECSHP_H
- #include "FWRecShp.h"
- #endif
-
- #ifndef FWPICSHP_H
- #include "FWPicShp.h"
- #endif
-
- // ----- Foundation Layer -----
-
- #ifndef FWNOTIFN_H
- #include "FWNotifn.h"
- #endif
-
- #ifndef FWNOTDEF_H
- #include "FWNotDef.h"
- #endif
-
- //========================================================================================
- // Runtime Informations
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfform
- #endif
-
- FW_DEFINE_AUTO(CFormFrame)
- FW_DEFINE_CLASS_M2(CFormFrame, FW_CFrame, FW_MReceiver)
-
- //========================================================================================
- // CFormFrame class
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::CFormFrame
- //----------------------------------------------------------------------------------------
- CFormFrame::CFormFrame(Environment* ev, ODFrame* odFrame, FW_CPresentation* presentation, CFormPart* part)
- : FW_CFrame(ev, odFrame, presentation, part),
- fFormPart(part),
- fIdler(NULL),
- fViewTabber(NULL)
- {
- // We must create an idler to see the caret blink in the text-edit views
- fIdler = FW_NEW(FW_CIdler, (this, 15));
- fIdler->RegisterIdle(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::~CFormFrame
- //----------------------------------------------------------------------------------------
-
- CFormFrame::~CFormFrame()
- {
- delete fIdler;
-
- // fViewTabber is deleted automatically because it's an attached event handler
- }
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::PostCreateViewFromStream
- //----------------------------------------------------------------------------------------
- // PostCreateViewFromStream is called after subviews are created from resources.
- // Implement initializations for this view that can't be done from a stream.
-
- void CFormFrame::PostCreateViewFromStream(Environment* ev)
- {
- // ----- Add a ViewTabber to the frame
- fViewTabber = new FW_CViewTabber(ev, this);
-
- // ----- Additional processing for non-root (i.e. embedded) frames
- if (IsRoot(ev) == false)
- {
- // Remove the GrowBox (delete is enough to remove it from the subviews list)
- FW_CView* growBox = FindViewById(ev, kGrowBoxID);
- FW_ASSERT(growBox);
- delete growBox;
-
- // Shrink the scroll-bars to leave space for a 1 pixel border
- // NOTE: It's against OpenDoc HI guidelines to keep scroll-bars in embedded frames
- // and also to have an embedded frame draw its own border!
- // Drawing the border should be the responsability of the container.
- // ... We wanted this sample to be different.
-
- FW_CView* hSB = FindViewById(ev, kHorzScrollBarID);
- FW_CPoint hSBLoc = hSB->GetLocation(ev);
- hSBLoc.x += FW_kFixedPos1;
- hSBLoc.y -= FW_kFixedPos1;
- FW_CPoint hSBSize = hSB->GetSize(ev);
- hSBSize.x -= FW_IntToFixed(2);
- hSB->SetLocation(ev, hSBLoc, false);
- hSB->SetSize(ev, hSBSize, false);
-
- FW_CView* vSB = FindViewById(ev, kVertScrollBarID);
- FW_CPoint vSBLoc = vSB->GetLocation(ev);
- vSBLoc.x -= FW_kFixedPos1;
- vSBLoc.y += FW_kFixedPos1;
- FW_CPoint vSBSize = vSB->GetSize(ev);
- vSBSize.y -= FW_IntToFixed(2);
- vSB->SetLocation(ev, vSBLoc, false);
- vSB->SetSize(ev, vSBSize, false);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::CreateSubViews
- //----------------------------------------------------------------------------------------
- // The subviews created for this frame are:
- //
- // CFormFrame
- // |_____ grow box (only for root frame)
- // |
- // |_____ horzSB (horizontal scrollbar)
- // |_____ vertSB (vertical scrollbar)
- // |
- // |_____ contentView (scrolling form)
- // |
- // |_____ <Several Controls>...
- //
- void CFormFrame::CreateSubViews(Environment* ev)
- {
- #if 1
-
- // WARNING: Make sure that classes created from resources won't be dead-stripped
- FW_DO_NOT_DEAD_STRIP(FW_CGrowBox);
- FW_DO_NOT_DEAD_STRIP(FW_CScrollBarScroller);
- FW_DO_NOT_DEAD_STRIP(FW_CGroupBox);
- FW_DO_NOT_DEAD_STRIP(FW_CScrollBar);
- FW_DO_NOT_DEAD_STRIP(FW_CEditView);
- FW_DO_NOT_DEAD_STRIP(FW_CListBox);
- FW_DO_NOT_DEAD_STRIP(FW_CButton);
- FW_DO_NOT_DEAD_STRIP(FW_CRadioCluster);
- FW_DO_NOT_DEAD_STRIP(FW_CPopupMenu);
-
- CreateSubViewsFromResource(ev, kFormView);
-
- #else
- // NOTE: This section is not compiled by default (change #if 1 by #if 0 above
- // and in FormView.cpp CFormView::CreateOwnSubViews())
- // It was left in the sample to show how to create views by program
- // instead of using resources. See also CFormView::CreateOwnSubViews().
-
- FW_CRect frameRect = GetBounds(ev);
- FW_CRect contentRect; // frame rect without scroll-bars
- GetContentRect(ev, contentRect);
-
- if (IsRoot(ev))
- {
- // ----- Create the GrowBox only in root frame
- FW_CGrowBox* growBox = new FW_CGrowBox(ev, this, 0, contentRect.BotRight());
- }
- else
- {
- // ----- Leave space to draw 1 pixel border in non-root frames
- frameRect.Inset(FW_kFixedPos1);
- }
-
- // ----- Create the vertical & horizontal scroll bars inside the frame
- FW_CRect vertSbRect(contentRect.right, frameRect.top - FW_kFixedPos1,
- frameRect.right + FW_kFixedPos1, contentRect.bottom + FW_kFixedPos1);
- FW_CScrollBar* vertSB = FW_NEW(FW_CScrollBar, (ev, this, 0, vertSbRect));
-
- FW_CRect horzSbRect(frameRect.left - FW_kFixedPos1, contentRect.bottom,
- contentRect.right + FW_kFixedPos1, frameRect.bottom + FW_kFixedPos1);
- FW_CScrollBar* horzSB = FW_NEW(FW_CScrollBar, (ev, this, 0,horzSbRect));
-
- // ----- Create the content view with the extent of the picture
- FW_CRect pictRect;
- fFormPart->GetPictShape1()->GetRectangle(pictRect);
- CFormView* contentView = new CFormView(ev, this, contentRect, pictRect.Size());
- contentView->MakeContentView(ev);
-
- // ----- Create the content view's subviews.
- // Note: We dispatch to a local method instead of creating all subviews here
- // only for clarity.
- contentView->CreateOwnSubViews(ev);
-
- // ----- Create a scroller (this must be done AFTER the content view)
- FW_CScroller* scroller = FW_NEW(FW_CScrollBarScroller, (ev, this, horzSB, vertSB));
- AdoptScroller(ev, scroller);
-
- // ----- Add a ViewTabber to the frame
- fViewTabber = new FW_CViewTabber(ev, this);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::GetContentRect
- //----------------------------------------------------------------------------------------
-
- void CFormFrame::GetContentRect(Environment* ev, FW_CRect& rect)
- {
- rect = GetBounds(ev);
-
- // Leave space to draw 1 pixel border in non-root frames
- if (IsRoot(ev) == FALSE)
- rect.Inset(FW_kFixedPos1);
-
- FW_CPoint sbSize = FW_CScrollBar::GetDefaultScrollBarSize();
-
- rect.right -= sbSize.x;
- rect.bottom -= sbSize.y;
- }
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::Draw
- //----------------------------------------------------------------------------------------
-
- void CFormFrame::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
- {
- FW_CRect contentRect;
- GetContentRect(ev, contentRect);
- FW_CRect formRect(GetFrame(ev)->GetContentView(ev)->GetBounds(ev));
-
- FW_CViewContext vc(ev, this, odFacet, invalidShape);
-
- // Draw a gray background around the content view if it's smaller
- if (formRect.right < contentRect.right || formRect.bottom < contentRect.bottom ) {
-
- // Draw outside the center view to avoid flashing
- FW_CAcquiredODShape aqPaneShape = ::FW_NewODShape(ev, contentRect);
- FW_CAcquiredODShape aqCenterShape = ::FW_NewODShape(ev, formRect);
- aqPaneShape->Subtract(ev, aqCenterShape);
-
- FW_CRegionShape::RenderRegion(vc, aqPaneShape, FW_kFill, FW_kRGBLightGray);
-
- // Draw a shadow frame around the content view
- formRect.Inset(-FW_kFixedPos1,-FW_kFixedPos1);
- FW_CRectShape::RenderRect(vc, formRect, FW_kFrame);
- FW_CPoint p1(formRect.left, formRect.bottom);
- FW_CPoint p2(formRect.right, formRect.bottom);
- FW_CPoint p3(formRect.right, formRect.top);
- if (formRect.bottom < contentRect.bottom - FW_kFixedPos1)
- FW_CLineShape::RenderLine(vc, p1, p2);
- if (formRect.right < contentRect.right - FW_kFixedPos1)
- FW_CLineShape::RenderLine(vc, p2, p3);
- }
-
- if (IsRoot(ev) == FALSE)
- {
- // Draw a 1 pixel border in non-root frames
- FW_CRect frameRect = GetBounds(ev);
- FW_CRectShape::RenderRect(vc, frameRect, FW_kFrame);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::FrameShapeChanged
- //----------------------------------------------------------------------------------------
-
- void CFormFrame::FrameShapeChanged(Environment *ev)
- {
- // By default a FW_CFrame view is not refreshed entirely when resized.
- // You must decide if your content's appearance depends on the frame's size.
- // If it doesn't you don't need to override FrameShapeChanged().
- // Here it's a little bit tricky because the formView is centered inside the frame,
- // so the only case where the content is fixed is when the frame is smaller than the
- // formView, i.e. the formView is anchored to the topleft corner.
-
- // Check if the formView was anchored before resizing
- FW_CRect contentRect;
- GetContentRect(ev, contentRect);
- FW_CSuperView* formView = GetFrame(ev)->GetContentView(ev);
- FW_CPoint formTopLeft(formView->GetBounds(ev).TopLeft());
- FW_Boolean anchoredBefore = (contentRect.TopLeft() == formTopLeft) ? TRUE : FALSE;
-
- // Resize the frame (this invalidates only the modified region)
- FW_CFrame::FrameShapeChanged(ev);
-
- // Check if the formView is anchored after resizing
- GetContentRect(ev, contentRect);
- formTopLeft = formView->GetBounds(ev).TopLeft();
- FW_Boolean anchoredAfter = (contentRect.TopLeft() == formTopLeft) ? TRUE : FALSE;
-
- // Invalidate the whole frame if we need redraw outside the formview
- if (!anchoredBefore || !anchoredAfter)
- Invalidate(ev);
- }
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::HandleNotification
- //----------------------------------------------------------------------------------------
-
- void CFormFrame::HandleNotification(Environment* ev, const FW_CNotification& notification)
- {
- // Handle notification messages for the registered controls.
- // GetMessage() allows to switch on the type of notification. For each message
- // we can down-cast "notification" directly to the right subclass, without
- // having to use RTTI, because the message is unique to that type.
-
- switch (notification.GetMessage())
- {
- case FW_kButtonPressedMsg:
- {
- const FW_CControlNotification& controlNotification =
- (FW_CControlNotification&) notification;
-
- // This frame has several active buttons, we must switch on the button id
- ODID viewId = controlNotification.GetViewId(ev);
- switch (viewId)
- {
- case kNoRadioID:
- // Show alert if "No" is being selected... and select "Yes" again :)
- if (controlNotification.GetControl(ev)->GetValue(ev) == 1)
- {
- // FW_Beep();
- FW_NoteAlert(FW_CString(), FW_CString(" We don't believe you! :-)"));
- FW_CButton* yesButton = (FW_CButton*) FindViewById(ev, kYesRadioID);
- yesButton->SetValue(ev, 1);
- }
- break;
-
- case kSubscribeButtonID:
- // Open modal dialog to pick a password
- OpenPasswordDialog(ev);
- break;
-
- case kAddButtonID:
- case kRemoveButtonID:
- // Add/Remove an item in the list box
- ModifyPlatformList(ev, viewId == kAddButtonID ? TRUE : FALSE);
- break;
- }
- }
- break;
-
- case FW_kPopupClickedMsg:
- {
- const FW_CPopupMenuNotification& popupNotification =
- (FW_CPopupMenuNotification&) notification;
- // no need to check ids, there is only 1 active popup (kBrowseTimePopupID)
- // Bring up an alert if the last item is selected
- if (popupNotification.GetMenuIndex(ev) == 4)
- {
- FW_CString alertString;
- popupNotification.GetMenuString(ev, alertString);
- alertString += "... that's too much!";
- FW_NoteAlert(FW_CString(), alertString);
- }
- }
- break;
-
- case FW_kListBoxDoubleClickedMsg:
- {
- const FW_CListBoxNotification& listBoxNotification =
- (FW_CListBoxNotification&) notification;
-
- // Beep if we double-click on the first item
- if (listBoxNotification.GetListBox(ev)->GetSelectedItem(ev) == 1)
- FW_Beep();
- }
- break;
-
- default:
- FW_ASSERT("CFormFrame can't respond to this");
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::OpenPasswordDialog
- //----------------------------------------------------------------------------------------
-
- void CFormFrame::OpenPasswordDialog(Environment* ev)
- {
- // position is not important here because we use FW_kStandardDialogPosition in the
- // window style to center the dialog properly.
- FW_CPoint position(FW_kZeroPoint);
- FW_CPoint size(FW_IntToFixed(300), FW_IntToFixed(160));
-
- FW_WindowStyle style = FW_kStandardDialogPosition | FW_kHasCaption;
-
- FW_CPresentation* dialogPresentation = GetFormPart()->GetPwdDialogPresentation();
-
- // ----- Create new dialog window with the "Password" presentation -----
- //
- // Note: unlike the standard Mac Toolbox "ModalDialog" FW_CDialogFrame::NewModalDialog
- // returns right after creating the dialog. Events are processed the same
- // way as any other OpenDoc frames, except that the modal focus is set.
- // (NewModalDialog can return NULL if the dialog creation failed because the
- // modal focus could not be granted)
- //
- // Here we use NewModalDialog() instead of NewAndShowModalDialog() because
- // we need to initialize a few things before opening the dialog
-
- CPwdDialogFrame* dialog = (CPwdDialogFrame*) FW_CDialogFrame::NewModalDialog(ev,
- GetPart(ev), // Your part
- dialogPresentation, // Used in CFormPart::NewFrame
- size, // Window size
- position, // Window position
- style, // Make dialog moveable
- FW_CString("Password")); // Title for moveable dialog
-
- if (dialog != NULL)
- {
- dialog->Initialize(ev, this);
- dialog->GetWindow(ev)->Show(ev);
- }
- }
- //----------------------------------------------------------------------------------------
- // CFormFrame::ModifyPlatformList
- //----------------------------------------------------------------------------------------
-
- void CFormFrame::ModifyPlatformList(Environment* ev, FW_Boolean addItem)
- {
- FW_CListBox* list = (FW_CListBox*)FindViewById(ev, kPlatformListBoxID);
- FW_ASSERT(list);
-
- if (addItem)
- {
- // Add a row after the last selected item or at the end.
- short addIndex = 0;
- short count = list->GetSelectionCount(ev);
-
- if (count > 0)
- {
- // We must retrieve the list of selected items in a dynamic array
- short* const indexArray = new short[count];
-
- short read = list->GetSelectedItems(ev, count, indexArray);
- FW_ASSERT(read == count);
-
- addIndex = indexArray[count - 1] + 1;
-
- delete indexArray;
- }
-
- list->AddStringItem(ev, FW_CString("Macintosh"), addIndex);
- list->ScrollIntoView(ev, addIndex);
- }
- else
- {
- // Remove the first selected item
- short selectedItem = list->GetSelectedItem(ev);
- if (selectedItem > 0)
- list->DeleteItems(ev, selectedItem);
-
- // Update button's state
- FW_CButton* rmButton = (FW_CButton*)FindViewById(ev, kRemoveButtonID);
- if (list->GetSelectedItem(ev) == 0)
- rmButton->Disable(ev);
- }
- }
-
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::NewPrintHandler
- //----------------------------------------------------------------------------------------
- // NewPrintHandler is all you need to support printing!
- // (You can also add a progress dialog resource as in ODF Draw's FWPrint.r but it's
- // not necessary and not very useful with background printing)
-
- FW_CPrintHandler* CFormFrame::NewPrintHandler(Environment* ev)
- {
- // We use the base PrintHandler class for basic printing of the content view
- // (See ODF Draw for a more advanced example)
- return new FW_CPrintHandler(fFormPart, this);
- }
-
-
- //----------------------------------------------------------------------------------------
- // CFormFrame::NewClipboardCommand
- //----------------------------------------------------------------------------------------
-
- FW_CClipboardCommand* CFormFrame::NewClipboardCommand(Environment* ev, ODCommandID commandID)
- {
- CEditViewCommand* cmd = FW_NEW(CEditViewCommand, (ev, commandID, this, FW_kCanUndo));
- return cmd;
- }
-
-